package com.zenithmind.task.utils;

import com.zenithmind.task.enums.TaskStatus;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 任务状态转换管理器
 * 遵循面向对象设计原则：
 * 1. 单一职责原则：专注于状态转换逻辑
 * 2. 开闭原则：通过策略模式支持状态转换规则扩展
 * 3. 依赖倒置原则：依赖抽象的状态转换接口
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Component
public class TaskStatusTransitionManager {

    /**
     * 状态转换策略接口
     */
    public interface StatusTransitionStrategy {
        /**
         * 检查是否可以转换
         * 
         * @param from 源状态
         * @param to 目标状态
         * @param context 转换上下文
         * @return 是否可以转换
         */
        boolean canTransition(TaskStatus from, TaskStatus to, TransitionContext context);

        /**
         * 执行转换前的操作
         * 
         * @param from 源状态
         * @param to 目标状态
         * @param context 转换上下文
         */
        void beforeTransition(TaskStatus from, TaskStatus to, TransitionContext context);

        /**
         * 执行转换后的操作
         * 
         * @param from 源状态
         * @param to 目标状态
         * @param context 转换上下文
         */
        void afterTransition(TaskStatus from, TaskStatus to, TransitionContext context);
    }

    /**
     * 转换上下文
     */
    public static class TransitionContext {
        private final String taskId;
        private final String userId;
        private final Map<String, Object> attributes;

        public TransitionContext(String taskId, String userId) {
            this.taskId = taskId;
            this.userId = userId;
            this.attributes = new HashMap<>();
        }

        public String getTaskId() {
            return taskId;
        }

        public String getUserId() {
            return userId;
        }

        public void setAttribute(String key, Object value) {
            attributes.put(key, value);
        }

        public Object getAttribute(String key) {
            return attributes.get(key);
        }

        @SuppressWarnings("unchecked")
        public <T> T getAttribute(String key, Class<T> type) {
            Object value = attributes.get(key);
            return type.isInstance(value) ? (T) value : null;
        }
    }

    /**
     * 默认状态转换策略
     */
    public static class DefaultTransitionStrategy implements StatusTransitionStrategy {
        @Override
        public boolean canTransition(TaskStatus from, TaskStatus to, TransitionContext context) {
            return from.canTransitionTo(to);
        }

        @Override
        public void beforeTransition(TaskStatus from, TaskStatus to, TransitionContext context) {
            // 默认空实现
        }

        @Override
        public void afterTransition(TaskStatus from, TaskStatus to, TransitionContext context) {
            // 默认空实现
        }
    }

    /**
     * 开始任务转换策略
     */
    public static class StartTaskStrategy implements StatusTransitionStrategy {
        @Override
        public boolean canTransition(TaskStatus from, TaskStatus to, TransitionContext context) {
            return to == TaskStatus.IN_PROGRESS && 
                   (from == TaskStatus.TODO || from == TaskStatus.PAUSED);
        }

        @Override
        public void beforeTransition(TaskStatus from, TaskStatus to, TransitionContext context) {
            // 检查前置条件，如依赖任务是否完成
            log.info("检查任务 {} 的开始条件", context.getTaskId());
        }

        @Override
        public void afterTransition(TaskStatus from, TaskStatus to, TransitionContext context) {
            // 记录开始时间、发送通知等
            log.info("任务 {} 已开始", context.getTaskId());
        }
    }

    /**
     * 完成任务转换策略
     */
    public static class CompleteTaskStrategy implements StatusTransitionStrategy {
        @Override
        public boolean canTransition(TaskStatus from, TaskStatus to, TransitionContext context) {
            return to == TaskStatus.COMPLETED && 
                   (from == TaskStatus.IN_PROGRESS || from == TaskStatus.TODO);
        }

        @Override
        public void beforeTransition(TaskStatus from, TaskStatus to, TransitionContext context) {
            // 检查完成条件，如子任务是否都完成
            log.info("检查任务 {} 的完成条件", context.getTaskId());
        }

        @Override
        public void afterTransition(TaskStatus from, TaskStatus to, TransitionContext context) {
            // 更新完成时间、计算实际工时、发送通知等
            log.info("任务 {} 已完成", context.getTaskId());
        }
    }

    // 状态转换策略映射
    private final Map<String, StatusTransitionStrategy> strategies = new HashMap<>();
    private final StatusTransitionStrategy defaultStrategy = new DefaultTransitionStrategy();

    public TaskStatusTransitionManager() {
        // 注册转换策略
        strategies.put("start", new StartTaskStrategy());
        strategies.put("complete", new CompleteTaskStrategy());
    }

    /**
     * 注册状态转换策略
     * 
     * @param name 策略名称
     * @param strategy 转换策略
     */
    public void registerStrategy(String name, StatusTransitionStrategy strategy) {
        strategies.put(name, strategy);
    }

    /**
     * 验证状态转换
     * 
     * @param from 源状态
     * @param to 目标状态
     * @param context 转换上下文
     * @return 是否可以转换
     */
    public boolean validateTransition(TaskStatus from, TaskStatus to, TransitionContext context) {
        if (from == null || to == null) {
            log.warn("状态不能为空: from={}, to={}", from, to);
            return false;
        }

        if (from == to) {
            log.warn("源状态和目标状态相同: {}", from);
            return false;
        }

        // 使用对应的策略验证
        StatusTransitionStrategy strategy = getStrategy(from, to);
        return strategy.canTransition(from, to, context);
    }

    /**
     * 执行状态转换
     * 
     * @param from 源状态
     * @param to 目标状态
     * @param context 转换上下文
     * @return 转换结果
     */
    public boolean executeTransition(TaskStatus from, TaskStatus to, TransitionContext context) {
        try {
            // 验证转换
            if (!validateTransition(from, to, context)) {
                log.warn("状态转换验证失败: {} -> {}", from, to);
                return false;
            }

            StatusTransitionStrategy strategy = getStrategy(from, to);

            // 执行转换前操作
            strategy.beforeTransition(from, to, context);

            // 这里应该调用实际的状态更新逻辑
            log.info("执行状态转换: {} -> {}, taskId={}", from, to, context.getTaskId());

            // 执行转换后操作
            strategy.afterTransition(from, to, context);

            return true;
        } catch (Exception e) {
            log.error("状态转换失败: {} -> {}, taskId={}", from, to, context.getTaskId(), e);
            return false;
        }
    }

    /**
     * 获取可转换的目标状态
     * 
     * @param from 源状态
     * @return 可转换的目标状态集合
     */
    public Set<TaskStatus> getAvailableTransitions(TaskStatus from) {
        if (from == null) {
            return Set.of();
        }

        return Set.of(TaskStatus.values())
                  .stream()
                  .filter(to -> from.canTransitionTo(to))
                  .collect(java.util.stream.Collectors.toSet());
    }

    /**
     * 获取状态转换策略
     * 
     * @param from 源状态
     * @param to 目标状态
     * @return 转换策略
     */
    private StatusTransitionStrategy getStrategy(TaskStatus from, TaskStatus to) {
        // 根据转换类型选择策略
        if (to == TaskStatus.IN_PROGRESS) {
            return strategies.getOrDefault("start", defaultStrategy);
        } else if (to == TaskStatus.COMPLETED) {
            return strategies.getOrDefault("complete", defaultStrategy);
        } else {
            return defaultStrategy;
        }
    }

    /**
     * 获取状态转换描述
     * 
     * @param from 源状态
     * @param to 目标状态
     * @return 转换描述
     */
    public String getTransitionDescription(TaskStatus from, TaskStatus to) {
        if (from == null || to == null) {
            return "无效的状态转换";
        }

        return String.format("将任务从 %s 转换为 %s", from.getName(), to.getName());
    }

    /**
     * 检查状态转换是否需要确认
     * 
     * @param from 源状态
     * @param to 目标状态
     * @return 是否需要确认
     */
    public boolean requiresConfirmation(TaskStatus from, TaskStatus to) {
        // 某些关键转换需要确认
        return to == TaskStatus.CANCELLED || to == TaskStatus.COMPLETED;
    }

    /**
     * 获取状态转换的建议操作
     * 
     * @param from 源状态
     * @param to 目标状态
     * @return 建议操作描述
     */
    public String getSuggestedAction(TaskStatus from, TaskStatus to) {
        if (from == null || to == null) {
            return "";
        }

        switch (to) {
            case IN_PROGRESS:
                return "请确保已准备好开始工作，并设置实际开始时间";
            case COMPLETED:
                return "请填写完成说明和实际工时";
            case PAUSED:
                return "请说明暂停原因";
            case CANCELLED:
                return "请说明取消原因";
            default:
                return "";
        }
    }
}
